#define _USE_MATH_DEFINES
#ifndef RANDOMNUMBERGENERATORS_HPP
#define RANDOMNUMBERGENERATORS_HPP
#include "srandInitializer.hpp"
#include "standardFunctions.hpp"
#include<cmath>


namespace TermStructure {
    //! Uniform 0-1 Generator
	template<typename T>
	class Uniform01Generator
	{
	public:
        //! Default Constructor
		Uniform01Generator()
		{
			_srandInitializer::SafeInitialize();
		}
        //! Get a new random variable
		T Next() const
		{
			return ((T)std::rand())/RAND_MAX;
		}
        //! Get a new random variable by inverting a uniform 0-1 random variable
		T InvertedFromUniform(const T& uniformRandomVariable) const
		{
			return uniformRandomVariable;
		}
	};


	template<typename T>
	class GaussGenerator
	{
	public:
        //! Get a new random variable
		T Next() const
		{
			T vn = 0;
			while(vn==0)
			{
				vn = _u.Next();
			}
			return std::sqrt(-2*std::log(vn))*std::cos(2*M_PI*_u.Next());
		} 
        //! Get a new random variable by inverting a uniform 0-1 random variable
		T InvertedFromUniform(const T& uniformRandomVariable) const
		{
			return std::sqrt(2)*_inverf(2*uniformRandomVariable-1);
		}
	protected:
		Uniform01Generator<T> _u;
		InverseErrorFunction<T> _inverf;
	};

	template<typename T>
	class ExponentialGenerator
	{
	public:
        //! Get a new random variable
		T Next() const
		{

		}
        //! Get a new random variable by inverting a uniform 0-1 random variable
		T InvertedFromUniform(const T& uniformRandomVariable) const
		{

		}
	};
}


#endif
